﻿using System;
using System.Collections.Generic;
using Family.Core;
using Family.Core.DataInterfaces;
using NHibernate;
using NHibernate.Criterion;
using Family.Core.Model;

namespace Family.Data.DBRepositories
{
    public class Repository<T> : IRepository<T> where T : EntityWithTypeId<Int32>
    {
        protected readonly ISession session;

        public Repository(ISession session)
        {
            Check.Require(session != null, new ArgumentNullException("session", "Argument of repository is NULL!"));

            this.session = session;
        }

        #region IRepository<T> Members

        public virtual void SaveOrUpdate(T entity)
        {
            Check.Require(entity != null, new ArgumentNullException("entity", "Argument of method is NULL!"));

            session.SaveOrUpdate(entity);
        }

        public virtual IList<T> GetAll()
        {
            var c = session.CreateCriteria(typeof(T));
            return c.List<T>();
        }

        public virtual void Delete(T entity)
        {
            Check.Require(entity != null, new ArgumentNullException("entity", "Argument of method is null!"));

            session.Delete(entity);
        }

        public virtual T Get(Int32 id)
        {
            Check.Require(id > 0, new ArgumentException("id must be greater then zero!"));

            return session.Get<T>(id);
        }

        //public T GetByCriteria(ICriteria criteria)
        //{
        //    Check.Require(criteria != null, new ArgumentException("criteria must be not null"));

        //    return criteria.UniqueResult() as T;
        //}

        public virtual ICriteria FindByCriteria(DetachedCriteria criteria)
        {
            return criteria.GetExecutableCriteria(session);
        }

        //public virtual EntityPage<T> GetPage(int pageNumber, int pageSize, string sortBy, bool ascending)
        //{
        //    return this.GetPage(pageNumber, pageSize, sortBy, ascending, null);
        //}

        //protected EntityPage<T> GetPage(int pageNumber, int pageSize, string sortBy, bool ascending, DetachedCriteria criteria)
        //{
        //    int firstResult = (pageNumber - 1) * pageSize;
        //    ICriteria pageCriteria = criteria == null
        //                                 ? this.session.CreateCriteria<T>()
        //                                 : criteria.GetExecutableCriteria(this.session);

        //    pageCriteria.AddOrder(new NHibernate.Criterion.Order(sortBy, ascending));
        //    pageCriteria.SetFirstResult(firstResult);
        //    pageCriteria.SetMaxResults(pageSize);
        //    IEnumerable<T> entitiesFromPage = pageCriteria.List<T>();

        //    ICriteria totalEntitiesCountCriteria = this.session.CreateCriteria<T>();
        //    int totalEntities = totalEntitiesCountCriteria.List().Count;

        //    var page = new EntityPage<T>(entitiesFromPage, totalEntities, pageNumber, pageSize);

        //    return page;
        //}

        #endregion
    }
}
